package ve.usb.ddp;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import ve.usb.cohesion.runtime.CohesionAction;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import ve.usb.cohesion.runtime.HibernateUtil;
import ve.usb.ddp.hibernate.*;

import java.util.List;
import java.awt.*;
import org.jCharts.axisChart.AxisChart;
import org.jCharts.axisChart.customRenderers.axisValue.renderers.ValueLabelPosition;
import org.jCharts.axisChart.customRenderers.axisValue.renderers.ValueLabelRenderer;
import org.jCharts.chartData.AxisChartDataSet;
import org.jCharts.chartData.DataSeries;
import org.jCharts.encoders.ServletEncoderHelper;
import org.jCharts.properties.*;
import org.jCharts.types.ChartType;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.codec.GifImage;
import com.itextpdf.text.Image;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URL;
import java.text.DecimalFormat;
import org.jCharts.encoders.PNGEncoder;

/**
 * 
 */
public class AccionesCU004EstadisticasPAI extends CohesionAction {
    
/**
     * Called by Struts for the execution of action A_Pre_PrincipalEstadisticasPAI.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward A_Pre_PrincipalEstadisticasPAI(ActionMapping mapping, ActionForm  form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"V_PrincipalEstadisticasPAI", };
        final int SALIDA_0 = 0;

        int salida = SALIDA_0;
//Checking for actors director_DDP, encargado_pai, encargado_pas, encargado_paa, encargado_prd
            if (!CohesionActor.checkActor(request, 62)) {
                return mapping.findForward(CohesionActor.SALIDA_ACTOR);
            }
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            /* Comienza nuestro codigo */
            F_Estd_PAI fF_Estd_PAI = new F_Estd_PAI();

            String queryInstituciones = "SELECT DISTINCT universidad FROM PaiEstudio";
            request.setAttribute("L_Instituciones", s.createQuery(queryInstituciones).list());

            String queryPaises = "SELECT DISTINCT pais FROM PaiEstudio";
            request.setAttribute("L_Paises", s.createQuery(queryPaises).list());

            String queryFuentes = "SELECT DISTINCT fuente FROM PaiFuenteFinanciamiento";
            request.setAttribute("L_Fuentes_Financiamiento", s.createQuery(queryFuentes).list());

            request.getSession().setAttribute("F_Estd_PAI", fF_Estd_PAI);
            /* Termina nuestro codigo */
            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try { s.close(); } catch (Exception ex2) {}
        }
        return mapping.findForward(SALIDAS[salida]);
    }

/**
     * Called by Struts for the execution of action A_Pre_ListarEstadisticaPAI.
     * 
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @return The Struts name of the following step.
     * @throws java.lang.Exception For untreated exceptions. 
     * These exceptios will normally be treated with 
     * the default exception action.
     */
    public ActionForward A_Pre_ListarEstadisticaPAI(ActionMapping mapping, ActionForm  form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        //Salidas
        final String[] SALIDAS = {"V_ListarEstadisticaPAI", "A_Pre_PrincipalEstadisticasPAI", };
        final int SALIDA_0 = 0;
        final int SALIDA_1 = 1;

        int salida = SALIDA_0;
//Checking for actors director_DDP, encargado_pai, encargado_paa, encargado_prd, encargado_pas
            if (!CohesionActor.checkActor(request, 62)) {
                return mapping.findForward(CohesionActor.SALIDA_ACTOR);
            }
        Session s = HibernateUtil.getCurrentSession();
        Transaction tr = s.beginTransaction();
        try {
            F_Estd_PAI fF_Estd_PAI = (F_Estd_PAI)form;
            /* Comienza nuestro codigo */
            String anioDesde = fF_Estd_PAI.getAnioDesde();
            String anioHasta = fF_Estd_PAI.getAnioHasta();
            // extraigo el tipo de estadistica a consultar
            String estadistica = request.getParameter("estadistica");
            
            String titulo_estadistica = "";
            List<Object[]> L_Profesores = null;
            AxisChart axisChart = null;

            if (estadistica.equals("participantes")) {
                titulo_estadistica = "Profesores Participantes";
                L_Profesores = participantes(anioHasta);
                axisChart = construirGrafico(estadistica,"",titulo_estadistica,anioDesde,anioHasta);
            }

            if (estadistica.equals("institucion")) {
                titulo_estadistica = "Profesores en la Institución " + fF_Estd_PAI.getInstitucion();
                L_Profesores = institucion(anioHasta, fF_Estd_PAI.getInstitucion());
                axisChart = construirGrafico(estadistica, fF_Estd_PAI.getInstitucion(),
                        titulo_estadistica, anioDesde, anioHasta);
            }

            if (estadistica.equals("fuenteFinanciamiento")) {
                titulo_estadistica = "Profesores Financiados por " + fF_Estd_PAI.getFuenteFinanciamiento();
                L_Profesores = fuenteFinanciamiento(anioHasta, fF_Estd_PAI.getFuenteFinanciamiento());
                axisChart = construirGrafico(estadistica, fF_Estd_PAI.getFuenteFinanciamiento(),
                        titulo_estadistica, anioDesde, anioHasta);
            }

            if (estadistica.equals("nivelEstudio")) {
                titulo_estadistica = "Profesores en nivel de estudio " + fF_Estd_PAI.getNivelEstudio();
                L_Profesores = nivelEstudio(anioHasta, fF_Estd_PAI.getNivelEstudio());
                axisChart = construirGrafico(estadistica, fF_Estd_PAI.getNivelEstudio(),
                        titulo_estadistica, anioDesde, anioHasta);
            }

            if (estadistica.equals("pais")) {
                titulo_estadistica = "Profesores en el país " + fF_Estd_PAI.getPais();
                L_Profesores = pais(anioHasta, fF_Estd_PAI.getPais());
                axisChart = construirGrafico(estadistica, fF_Estd_PAI.getPais(),
                        titulo_estadistica, anioDesde, anioHasta);
            }

            if (estadistica.equals("modalidadEstudio")) {
                titulo_estadistica = "Profesores en modalidad " + fF_Estd_PAI.getModalidadEstudio();
                L_Profesores = modalidadEstudio(anioHasta, fF_Estd_PAI.getModalidadEstudio());
                axisChart = construirGrafico(estadistica, fF_Estd_PAI.getModalidadEstudio(),
                        titulo_estadistica, anioDesde, anioHasta);
            }

            if (estadistica.equals("enEstudio")) {
                titulo_estadistica = "Profesores en Estudio";
                L_Profesores = enEstudio(anioHasta);
                axisChart = construirGrafico(estadistica, "", titulo_estadistica, anioDesde, anioHasta);
            }

            if (estadistica.equals("desincorporados")) {
                titulo_estadistica = "Profesores Desincorporados";
                L_Profesores = desincorporados(anioHasta);
                axisChart = construirGrafico(estadistica, "", titulo_estadistica, anioDesde, anioHasta);
            }

            if (estadistica.equals("culminaron")) {
                titulo_estadistica = "Profesores que Culminaron Estudios";
                L_Profesores = culminaron(anioHasta);
                axisChart = construirGrafico(estadistica, "", titulo_estadistica, anioDesde, anioHasta);
            }

            if (estadistica.equals("culminaronRenunciaron")) {
                titulo_estadistica = "Profesores que Culminaron Estudios y Renunciaron";
                L_Profesores = culminaronRenunciaron(anioHasta);
                axisChart = construirGrafico(estadistica, "", titulo_estadistica, anioDesde, anioHasta);
            }

            if (estadistica.equals("renunciaronSinCulminar")) {
                titulo_estadistica = "Profesores que Renunciaron Sin Culminar Estudios";
                L_Profesores = renunciaronSinCulminar(anioHasta);
                axisChart = construirGrafico(estadistica, "", titulo_estadistica, anioDesde, anioHasta);
            }

            if (L_Profesores.isEmpty()) {
                salida = SALIDA_1;
            } else {
                String mensajeTotal = "Hay " + L_Profesores.size() + " " +
                        titulo_estadistica + " durante el año " + anioHasta + 
                        ", de un total de " + participantes(anioHasta).size() + " profesores " +
                        "participantes durante el año " + anioHasta + ", lo que representa una porción de " +
                        getPorcentaje(L_Profesores.size(), participantes(anioHasta).size()) + ".";
                ByteArrayOutputStream baosPDF = construirPDF(L_Profesores,
                        "PAI - " + titulo_estadistica + " durante el año " + anioHasta, axisChart, mensajeTotal);
                request.getSession().setAttribute("titulo_estadistica", titulo_estadistica);
                request.getSession().setAttribute("anioDesde", anioDesde);
                request.getSession().setAttribute("anioHasta", anioHasta);
                request.getSession().setAttribute("tipoEstadistica", estadistica);
                request.getSession().setAttribute("L_Profesores", L_Profesores);
                request.getSession().setAttribute("Grafico", axisChart);
                request.getSession().setAttribute("mensajeTotal", mensajeTotal);
                request.getSession().setAttribute("nombrePDF",
                        "PAI - " + titulo_estadistica + " durante el año " + anioHasta + ".pdf");
                request.getSession().setAttribute("baosPDF", baosPDF);

                fF_Estd_PAI.reset(mapping, request);
            }
            /* Termina nuestro codigo */
            tr.commit();

        } catch (Exception ex) {
            tr.rollback();
            throw ex;
        } finally {
            try { s.close(); } catch (Exception ex2) {}
        }
        if (salida==1) {
          request.setAttribute("msg","La consulta no arrojó resultados");
        }
        return mapping.findForward(SALIDAS[salida]);
    }

    public void A_GraficaEstadisticaPAI(ActionMapping mapping, ActionForm  form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        AxisChart axisChart = (AxisChart) request.getSession().getAttribute("Grafico");
        ServletEncoderHelper.encodePNG(axisChart, response);
    }

    public void A_PDFEstadisticaPAI(ActionMapping mapping, ActionForm  form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        String nombrePDF = (String) request.getSession().getAttribute("nombrePDF");
        ByteArrayOutputStream baosPDF = (ByteArrayOutputStream) request.getSession().getAttribute("baosPDF");

        // Le indico al Servlet que voy a enviar un archivo pdf
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", " attachment; filename=\"" + nombrePDF + "\"");

        baosPDF.writeTo(response.getOutputStream());
    }

    private AxisChart construirGrafico(String estadistica, String otroValor,
            String titulo_estadistica, String anioDesde, String anioHasta) throws Exception {
        
        int ancho = 640;
        int alto = 480;
        String title = titulo_estadistica + " desde el año " + anioDesde + " hasta el año " + anioHasta;
        String xAxisTitle= "Años";
        String yAxisTitle= "Número de Profesores";
        String[] legendLabels= { titulo_estadistica };
        Paint[] paints= new Paint[]{ Color.blue.darker() };

        int anioInicio = Integer.parseInt(anioDesde);
        int anioFin = Integer.parseInt(anioHasta);
        
        String[] xAxisLabels = new String[anioFin-anioInicio+1];
        double[][] data= new double[1][anioFin-anioInicio+1];

        int i = 0;
        for(; anioInicio <= anioFin; anioInicio++) {
            xAxisLabels[i] = String.valueOf(anioInicio);
            if (estadistica.equals("participantes")) {
                data[0][i] = participantes(xAxisLabels[i]).size();
            } else if (estadistica.equals("institucion")) {
                data[0][i] = institucion(xAxisLabels[i], otroValor).size();
            } else if (estadistica.equals("fuenteFinanciamiento")) {
                data[0][i] = fuenteFinanciamiento(xAxisLabels[i], otroValor).size();
            } else if (estadistica.equals("nivelEstudio")) {
                data[0][i] = nivelEstudio(xAxisLabels[i], otroValor).size();
            } else if (estadistica.equals("pais")) {
                data[0][i] = pais(xAxisLabels[i], otroValor).size();
            } else if (estadistica.equals("modalidadEstudio")) {
                data[0][i] = modalidadEstudio(xAxisLabels[i], otroValor).size();
            } else if (estadistica.equals("enEstudio")) {
                data[0][i] = enEstudio(xAxisLabels[i]).size();
            } else if (estadistica.equals("desincorporados")) {
                data[0][i] = desincorporados(xAxisLabels[i]).size();
            } else if (estadistica.equals("culminaron")) {
                data[0][i] = culminaron(xAxisLabels[i]).size();
            } else if (estadistica.equals("culminaronRenunciaron")) {
                data[0][i] = culminaronRenunciaron(xAxisLabels[i]).size();
            } else if (estadistica.equals("renunciaronSinCulminar")) {
                data[0][i] = renunciaronSinCulminar(xAxisLabels[i]).size();
            }
            i++;
        }

        DataSeries dataSeries = new DataSeries( xAxisLabels, xAxisTitle, yAxisTitle, title );

        BarChartProperties barChartProperties= new BarChartProperties();
        ValueLabelRenderer valueLabelRenderer = new ValueLabelRenderer(false, false, true, 0);
        valueLabelRenderer.setValueLabelPosition( ValueLabelPosition.ON_TOP );
        valueLabelRenderer.useVerticalLabels( false );
        barChartProperties.addPostRenderEventListener( valueLabelRenderer );

        AxisChartDataSet axisChartDataSet= new AxisChartDataSet( data, legendLabels, paints, ChartType.BAR, barChartProperties );
        dataSeries.addIAxisPlotDataSet( axisChartDataSet );

        ChartProperties chartProperties= new ChartProperties();

        AxisProperties axisProperties= new AxisProperties();
        LegendProperties legendProperties= new LegendProperties();
        AxisChart axisChart = new AxisChart(dataSeries, chartProperties, axisProperties, legendProperties, ancho, alto);

        return axisChart;
    }

    private ByteArrayOutputStream construirPDF(List<Object[]> L_Profesor, String titulo,
            AxisChart axisChart, String mensajeTotal) throws Exception {

        // Nuevo documento PDF con la pagina horizontal
        Document document = new Document(PageSize.LETTER.rotate());
        ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();
        PdfWriter.getInstance(document, baosPDF);

        document.open();

        //Seteo de la cebolla
        URL base = this.getClass().getResource("");
        String path = new File(base.getFile(), "/../../../../../css/images/Cebolla001tr.gif").getCanonicalPath();
        GifImage img = new GifImage(path);
        int frame_count = img.getFrameCount();
        for(int i = 1; i <= frame_count; i++){
            document.add(img.getImage(i));
        }
        //Seteo Membrete
        document.add(new Paragraph("Universidad Simón Bolívar\nDepartamento de Desarrollo Profesoral\n" +
                                   "Programa Actualización Académica"));

        //Seteo el titulo y lo agrego al documento
        Paragraph title = new Paragraph(titulo, FontFactory.getFont(FontFactory.HELVETICA, 18, Font.BOLD));
        title.setAlignment(Element.ALIGN_CENTER);
        title.setSpacingAfter(25);
        document.add(title);

        //Defino las relaciones de tamano entre las columnas
        float[] anchos = new float[7];
        anchos[0] = 12;//Apellidos
        anchos[1] = 12;//Nombres
        anchos[2] = 8;//Cedula
        anchos[3] = 15;//Email
        anchos[4] = 10;//Categoria
        anchos[5] = 10;//Division
        anchos[6] = 11;//Departamento

        //Creo la tabla
        PdfPTable table = new PdfPTable(7);
        table.setWidthPercentage(100);
        table.setWidths(anchos);

        //Anado los headers a la tabla
        table.addCell("Apellidos");
        table.addCell("Nombres");
        table.addCell("Cédula");
        table.addCell("Email");
        table.addCell("Categoría");
        table.addCell("División");
        table.addCell("Departamento");

        //Agrego los datos a la tabla
        for (Object[] prof : L_Profesor) {
            table.addCell((String)prof[0].toString() + " " + (String)prof[1].toString());//Apellidos
            table.addCell((String)prof[2].toString() + " " + (String)prof[3].toString());//Nombres
            table.addCell(String.valueOf(prof[4].toString()));//Cedula
            table.addCell((String)prof[5].toString());//Email
            table.addCell((String)prof[6].toString());//Categoria
            table.addCell((String)prof[7].toString());//Division
            table.addCell((String)prof[8].toString());//Departamento
        }
        // Agrego la tabla creada al documento
        document.add(table);

        //mensaje de porcentaje
        document.add(new Paragraph(mensajeTotal));

        // Agrego el grafico
        ByteArrayOutputStream baosGrafico = new ByteArrayOutputStream();
        PNGEncoder.encode(axisChart, baosGrafico);
        Image barChartImage = Image.getInstance(baosGrafico.toByteArray());
        document.add(barChartImage);

        document.close();

        return baosPDF;
    }

    private String getPorcentaje(int porcion, int total) {
        // Saco la fraccion del valor sobre el total
        Double fraccion = porcion / Long.valueOf(String.valueOf(total)).doubleValue();

        return new DecimalFormat("##0.00%").format(fraccion);
    }

    private List<Object[]> participantes(String anio) throws Exception {
        Session s = HibernateUtil.getCurrentSession();
        try {
            String query = "SELECT DISTINCT prof.primerApellido, prof.segundoApellido, " +
                    "prof.primerNombre, prof.segundoNombre, prof.ci, prof.correo, " +
                    "prof.categoria, prof.division, prof.departamento " +
                    "FROM Profesor prof, Pai pai " +
                    "WHERE pai.profesor = prof.idprofesor " +
                    // Comparo la fecha de inicio del PAI
                    "AND date_part('year', pai.fec_ini) <= " + anio + " " +
                    // Chequeo que no se haya desincorporado antes [NO FUNCIONA]
//                    "AND " + anio + "<= (SELECT date_part('year', des.fecha) " +
//                    "                    FROM PaiDesincorporacion des, PaiResolucion res " +
//                    "                    WHERE res.pai = pai.idpai AND " +
//                    "                    des.resolucion = res.idresolucion AND " +
//                                         // Ultima resolucion que tenga una desincorporacion asociada
//                    "                    res.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
//                    "                                          FROM PaiResolucion resAux " +
//                    "                                          WHERE resAux.pai = pai.idpai AND " +
//                    "                                          resAux.desincorporacion IS NOT NULL" +
//                    "                                         ) " +
//                    "                   ) " +
                    // Comparo la fecha de finaliacion del PAI
                    "AND (" + anio + " <= date_part('year', pai.fec_fin) " +
                      // En caso que se le haya dado prorroga
                    "     OR " + anio + " <= (SELECT date_part('year', pro.fec_fin) " +
                    "                         FROM PaiProrroga pro, PaiResolucion res " +
                    "                         WHERE res.pai = pai.idpai AND " +
                    "                         pro.resolucion = res.idresolucion AND " +
                                              // Ultima resolucion que tenga una prorroga asociada
                    "                         res.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
                    "                                               FROM PaiResolucion resAux " +
                    "                                               WHERE resAux.pai = pai.idpai AND " +
                    "                                               resAux.prorroga IS NOT NULL " +
                    "                                              ) " +
                    "                        ) " +
                    "   )";
            return s.createSQLQuery(query).list();
        } catch (Exception ex) {
            throw ex;
        }
    }

    private List<Object[]> institucion(String anio, String institucion) throws Exception {
        Session s = HibernateUtil.getCurrentSession();
        try {
String query = "SELECT DISTINCT prof.primerApellido, prof.segundoApellido, " +
                    "prof.primerNombre, prof.segundoNombre, prof.ci, prof.correo, " +
                    "prof.categoria, prof.division, prof.departamento " +
                    "FROM Profesor prof, Pai pai, PaiEstudio est, PaiResolucion resolucion " +
                    "WHERE pai.profesor = prof.idprofesor " +
                    // Comparo la fecha de inicio del PAI
                    "AND date_part('year', pai.fec_ini) <= " + anio + " " +
                    // Comparo la fecha de finaliacion del PAI
                    "AND (" + anio + " <= date_part('year', pai.fec_fin) " +
                      // En caso que se le haya dado prorroga
                    "     OR " + anio + " <= (SELECT date_part('year', pro.fec_fin) " +
                    "                         FROM PaiProrroga pro, PaiResolucion res " +
                    "                         WHERE res.pai = pai.idpai " +
                    "                         AND pro.resolucion = res.idresolucion " +
                                       // Ultima resolucion que tenga una prorroga asociada
                    "                         AND res.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
                    "                                                   FROM PaiResolucion resAux " +
                    "                                                   WHERE resAux.pai = pai.idpai " +
                    "                                                   AND resAux.prorroga IS NOT NULL" +
                    "                                                  ) " +
                    "                        ) " +
                    "    )" +
                    "AND resolucion.pai = pai.idpai " +
                    "AND est.resolucion = resolucion.idresolucion " +
                    "AND est.universidad = '" + institucion + "'";
            return s.createSQLQuery(query).list();
        } catch (Exception ex) {
            throw ex;
        }
    }

    private List<Object[]> fuenteFinanciamiento(String anio, String fuente) throws Exception {
        Session s = HibernateUtil.getCurrentSession();
        try {
String query = "SELECT DISTINCT prof.primerApellido, prof.segundoApellido, " +
                    "prof.primerNombre, prof.segundoNombre, prof.ci, prof.correo, " +
                    "prof.categoria, prof.division, prof.departamento " +
                    "FROM Profesor prof, Pai pai, PaiResolucion resolucion, " +
                    "PaiRemuneracion rem, PaiFuenteFinanciamiento fuente " +
                    "WHERE pai.profesor = prof.idprofesor " +
                    // Comparo la fecha de inicio del PAI
                    "AND date_part('year', pai.fec_ini) <= " + anio + " " +
                    // Comparo la fecha de finaliacion del PAI
                    "AND (" + anio + " <= date_part('year', pai.fec_fin) " +
                      // En caso que se le haya dado prorroga
                    "     OR " + anio + " <= (SELECT date_part('year', pro.fec_fin) " +
                    "                         FROM PaiProrroga pro, PaiResolucion res " +
                    "                         WHERE res.pai = pai.idpai AND " +
                    "                         pro.resolucion = res.idresolucion AND " +
                                              // Ultima resolucion que tenga una prorroga asociada
                    "                         res.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
                    "                                               FROM PaiResolucion resAux " +
                    "                                               WHERE resAux.pai = pai.idpai AND " +
                    "                                               resAux.prorroga IS NOT NULL " +
                    "                                              ) " +
                    "                        ) " +
                    "    ) " +
                    "AND resolucion.pai = pai.idpai " +
                    "AND rem.resolucion = resolucion.idresolucion " +
                    "AND fuente.remuneracion = rem.idremuneracion " +
                    "AND fuente.fuente = '" + fuente + "'";
            return s.createSQLQuery(query).list();
        } catch (Exception ex) {
            throw ex;
        }
    }

    private List<Object[]> nivelEstudio(String anio, String nivel) throws Exception {
        Session s = HibernateUtil.getCurrentSession();
        try {
String query = "SELECT DISTINCT prof.primerApellido, prof.segundoApellido, " +
                    "prof.primerNombre, prof.segundoNombre, prof.ci, prof.correo, " +
                    "prof.categoria, prof.division, prof.departamento " +
                    "FROM Profesor prof, Pai pai, PaiEstudio est, PaiResolucion resolucion " +
                    "WHERE pai.profesor = prof.idprofesor " +
                    // Comparo la fecha de inicio del PAI
                    "AND date_part('year', pai.fec_ini) <= " + anio + " " +
                    // Comparo la fecha de finaliacion del PAI
                    "AND (" + anio + " <= date_part('year', pai.fec_fin) " +
                      // En caso que se le haya dado prorroga
                    "     OR " + anio + " <= (SELECT date_part('year', pro.fec_fin) " +
                    "                         FROM PaiProrroga pro, PaiResolucion res " +
                    "                         WHERE res.pai = pai.idpai " +
                    "                         AND pro.resolucion = res.idresolucion " +
                                       // Ultima resolucion que tenga una prorroga asociada
                    "                         AND res.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
                    "                                                   FROM PaiResolucion resAux " +
                    "                                                   WHERE resAux.pai = pai.idpai " +
                    "                                                   AND resAux.prorroga IS NOT NULL" +
                    "                                                  ) " +
                    "                        ) " +
                    "    )" +
                    "AND resolucion.pai = pai.idpai " +
                    "AND est.resolucion = resolucion.idresolucion " +
                    "AND est.nivel = '" + nivel + "'";
            return s.createSQLQuery(query).list();
        } catch (Exception ex) {
            throw ex;
        }
    }

    private List<Object[]> pais(String anio, String pais) throws Exception {
        Session s = HibernateUtil.getCurrentSession();
        try {
String query = "SELECT DISTINCT prof.primerApellido, prof.segundoApellido, " +
                    "prof.primerNombre, prof.segundoNombre, prof.ci, prof.correo, " +
                    "prof.categoria, prof.division, prof.departamento " +
                    "FROM Profesor prof, Pai pai, PaiEstudio est, PaiResolucion resolucion " +
                    "WHERE pai.profesor = prof.idprofesor " +
                    // Comparo la fecha de inicio del PAI
                    "AND date_part('year', pai.fec_ini) <= " + anio + " " +
                    // Comparo la fecha de finaliacion del PAI
                    "AND (" + anio + " <= date_part('year', pai.fec_fin) " +
                      // En caso que se le haya dado prorroga
                    "     OR " + anio + " <= (SELECT date_part('year', pro.fec_fin) " +
                    "                         FROM PaiProrroga pro, PaiResolucion res " +
                    "                         WHERE res.pai = pai.idpai " +
                    "                         AND pro.resolucion = res.idresolucion " +
                                       // Ultima resolucion que tenga una prorroga asociada
                    "                         AND res.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
                    "                                                   FROM PaiResolucion resAux " +
                    "                                                   WHERE resAux.pai = pai.idpai " +
                    "                                                   AND resAux.prorroga IS NOT NULL" +
                    "                                                  ) " +
                    "                        ) " +
                    "    )" +
                    "AND resolucion.pai = pai.idpai " +
                    "AND est.resolucion = resolucion.idresolucion " +
                    "AND est.pais = '" + pais + "'";
            return s.createSQLQuery(query).list();
        } catch (Exception ex) {
            throw ex;
        }
    }

    private List<Object[]> modalidadEstudio(String anio, String modalidad) throws Exception {
        Session s = HibernateUtil.getCurrentSession();
        try {
        String query = "SELECT DISTINCT prof.primerApellido, prof.segundoApellido, " +
                    "prof.primerNombre, prof.segundoNombre, prof.ci, prof.correo, " +
                    "prof.categoria, prof.division, prof.departamento " +
                    "FROM Profesor prof, Pai pai, PaiEstudio est, PaiResolucion resolucion " +
                    "WHERE pai.profesor = prof.idprofesor " +
                    // Comparo la fecha de inicio del PAI
                    "AND date_part('year', pai.fec_ini) <= " + anio + " " +
                    // Comparo la fecha de finaliacion del PAI
                    "AND (" + anio + " <= date_part('year', pai.fec_fin) " +
                      // En caso que se le haya dado prorroga
                    "     OR " + anio + " <= (SELECT date_part('year', pro.fec_fin) " +
                    "                         FROM PaiProrroga pro, PaiResolucion res " +
                    "                         WHERE res.pai = pai.idpai " +
                    "                         AND pro.resolucion = res.idresolucion " +
                                       // Ultima resolucion que tenga una prorroga asociada
                    "                         AND res.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
                    "                                                   FROM PaiResolucion resAux " +
                    "                                                   WHERE resAux.pai = pai.idpai " +
                    "                                                   AND resAux.prorroga IS NOT NULL" +
                    "                                                  ) " +
                    "                        ) " +
                    "    )" +
                    "AND resolucion.pai = pai.idpai " +
                    "AND est.resolucion = resolucion.idresolucion " +
                    "AND est.modalidad = '" + modalidad + "'";
            return s.createSQLQuery(query).list();
        } catch (Exception ex) {
            throw ex;
        }
    }

    private List<Object[]> enEstudio(String anio) throws Exception {
        Session s = HibernateUtil.getCurrentSession();
        try {
            String query = "SELECT DISTINCT prof.primerApellido, prof.segundoApellido, " +
                    "prof.primerNombre, prof.segundoNombre, prof.ci, prof.correo, " +
                    "prof.categoria, prof.division, prof.departamento " +
                    "FROM Profesor prof, Pai pai, PaiEstudio est, PaiResolucion resolucion " +
                    "WHERE pai.profesor = prof.idprofesor " +
                    "AND resolucion.pai = pai.idpai " +
                    // Ultima resolucion con un estudio asociado
                    "AND resolucion.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
                    "                                 FROM PaiResolucion resAux " +
                    "                                 WHERE resAux.pai = pai.idpai " +
                    "                                 AND resAux.estudio IS NOT NULL" +
                    "                                ) " +
                    "AND est.resolucion = resolucion.idresolucion " +
                    // Comparo la fecha de inicio del estudio
                    "AND date_part('year', est.fec_Ini) <= " + anio + " " +
                    // Comparo la fecha de finalizacion del estudio
                    "AND " + anio + " <= date_part('year', est.fec_Fin)";
            return s.createSQLQuery(query).list();
        } catch (Exception ex) {
            throw ex;
        }
    }

    private List<Object[]> desincorporados(String anio) throws Exception {
        Session s = HibernateUtil.getCurrentSession();
        try {
            String query = "SELECT DISTINCT prof.primerApellido, prof.segundoApellido, " +
                    "prof.primerNombre, prof.segundoNombre, prof.ci, prof.correo, " +
                    "prof.categoria, prof.division, prof.departamento " +
                    "FROM Profesor prof, Pai pai, PaiResolucion resolucion, PaiDesincorporacion des" +
                    "WHERE pai.profesor = prof.idprofesor " +
                    "AND resolucion.pai = pai.idpai " +
                    // Ultima resolucion con una desincorporacion asociada
                    "AND resolucion.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
                    "                                 FROM PaiResolucion resAux " +
                    "                                 WHERE resAux.pai = pai.idpai " +
                    "                                 AND resAux.desincorporacion IS NOT NULL" +
                    "                                ) " +
                    "AND des.resolucion = resolucion.idresolucion " +
                    // Chequeo si se desincorporo durante anio
                    "AND " + anio + " = date_part('year', des.fecha)";
            return s.createSQLQuery(query).list();
        } catch (Exception ex) {
            throw ex;
        }
    }

    private List<Object[]> culminaron(String anio) throws Exception {
        Session s = HibernateUtil.getCurrentSession();
        try {
            String query = "SELECT DISTINCT prof.primerApellido, prof.segundoApellido, " +
                    "prof.primerNombre, prof.segundoNombre, prof.ci, prof.correo, " +
                    "prof.categoria, prof.division, prof.departamento " +
                    "FROM Profesor prof, Pai pai, PaiEstudio est, PaiResolucion resolucion " +
                    "WHERE pai.profesor = prof.idprofesor " +
                    "AND resolucion.pai = pai.idpai " +
                    // Ultima resolucion con un estudio asociado
                    "AND resolucion.fec_Resolucion = (SELECT MAX(resAux.fec_Resolucion) " +
                    "                                 FROM PaiResolucion resAux " +
                    "                                 WHERE resAux.pai = pai.idpai " +
                    "                                 AND resAux.estudio IS NOT NULL" +
                    "                                ) " +
                    "AND est.resolucion = resolucion.idresolucion " +
                    // Chequeo si termino el estudio durante anio
                    "AND " + anio + " = date_part('year', est.fec_Fin)";
            return s.createSQLQuery(query).list();
        } catch (Exception ex) {
            throw ex;
        }
    }

    private List<Object[]> culminaronRenunciaron(String anio) throws Exception {
        return null;
    }

    private List<Object[]> renunciaronSinCulminar(String anio) throws Exception {
        return null;
    }
}